import { useState, useEffect, useCallback } from 'react';
import { multiChainApi } from '@/lib/multi-chain-api';
import { useChain } from '@/context/ChainContext';
import { API_ENDPOINTS } from '@/config/api';

export interface BlockchainStatus {
  connected: boolean;
  latest_block: number;
  network: string;
  network_name: string;
  chain_id: number;
  explorer_url: string;
  dtv_contract: string;
  staking_contract: string;
  is_testnet: boolean;
  error?: string;
}

export interface BackgroundTaskStatus {
  is_running: boolean;
  task_count: number;
  tasks: {
    [key: string]: {
      done: boolean;
      cancelled: boolean;
      exception: string | null;
    };
  };
}

export interface MonitoringStatus {
  is_active: boolean;
  contracts_initialized: boolean;
  error?: string;
}

export interface SyncStatusData {
  blockchain: BlockchainStatus;
  background_tasks: BackgroundTaskStatus;
  monitoring: MonitoringStatus;
}

export interface EventStats {
  total_events: number;
  processed_events: number;
  failed_events: number;
  event_types: { [key: string]: number };
  contracts: { [key: string]: number };
}

export interface BlockchainStats {
  total_events: number;
  processed_events: number;
  pending_events: number;
  failed_events: number;
  last_sync_block: number;
  contracts_monitored: number;
}

export const useSyncStatus = (autoRefresh = true, refreshInterval = 30000) => {
  const { currentChain } = useChain();
  const [syncStatus, setSyncStatus] = useState<SyncStatusData | null>(null);
  const [eventStats, setEventStats] = useState<EventStats | null>(null);
  const [blockchainStats, setBlockchainStats] = useState<BlockchainStats | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null);

  const fetchSyncStatus = useCallback(async () => {
    try {
      setError(null);
      const client = multiChainApi.getClient(currentChain);
      const response = await client.get(API_ENDPOINTS.admin.blockchainStatus);
      setSyncStatus(response.data);
      setLastUpdated(new Date());
    } catch (err: any) {
      console.error('Failed to fetch sync status:', err);
      setError(err.response?.data?.detail || 'Failed to fetch sync status');
    }
  }, [currentChain]);

  const fetchEventStats = useCallback(async () => {
    try {
      const client = multiChainApi.getClient(currentChain);
      const response = await client.get(API_ENDPOINTS.blockchainEvents.stats);
      setEventStats(response.data);
    } catch (err: any) {
      console.error('Failed to fetch event stats:', err);
      // Don't set error for event stats as it's supplementary data
    }
  }, [currentChain]);

  const fetchBlockchainStats = useCallback(async () => {
    try {
      const client = multiChainApi.getClient(currentChain);
      const response = await client.get(API_ENDPOINTS.admin.blockchainStats);
      setBlockchainStats(response.data);
    } catch (err: any) {
      console.error('Failed to fetch blockchain stats:', err);
      // Don't set error for blockchain stats as it's supplementary data
    }
  }, [currentChain]);

  const fetchAllData = useCallback(async () => {
    setLoading(true);
    await Promise.all([
      fetchSyncStatus(),
      fetchEventStats(),
      fetchBlockchainStats()
    ]);
    setLoading(false);
  }, [fetchSyncStatus, fetchEventStats, fetchBlockchainStats]);

  const refresh = useCallback(() => {
    fetchAllData();
  }, [fetchAllData]);

  useEffect(() => {
    fetchAllData();
  }, [fetchAllData]);

  useEffect(() => {
    if (!autoRefresh) return;

    const interval = setInterval(() => {
      fetchAllData();
    }, refreshInterval);

    return () => clearInterval(interval);
  }, [autoRefresh, refreshInterval, fetchAllData]);

  // Calculate sync progress
  const syncProgress = eventStats ? {
    percentage: eventStats.total_events > 0 
      ? Math.round((eventStats.processed_events / eventStats.total_events) * 100) 
      : 100,
    processed: eventStats.processed_events,
    total: eventStats.total_events,
    failed: eventStats.failed_events,
    pending: eventStats.total_events - eventStats.processed_events - eventStats.failed_events
  } : null;

  // Determine overall health status
  const healthStatus = (() => {
    if (!syncStatus) return 'unknown';
    
    const isBlockchainConnected = syncStatus.blockchain?.connected;
    const isMonitoringActive = syncStatus.monitoring?.is_active;
    const areTasksRunning = syncStatus.background_tasks?.is_running;
    const hasFailedTasks = Object.values(syncStatus.background_tasks?.tasks || {})
      .some(task => task.exception || task.cancelled);

    if (isBlockchainConnected && isMonitoringActive && areTasksRunning && !hasFailedTasks) {
      return 'healthy';
    } else if (isBlockchainConnected && isMonitoringActive) {
      return 'warning';
    } else {
      return 'error';
    }
  })();

  return {
    syncStatus,
    eventStats,
    blockchainStats,
    syncProgress,
    healthStatus,
    loading,
    error,
    lastUpdated,
    refresh
  };
};